import { ElDrawer, ElNotification } from 'element-plus';
import 'element-plus/theme-chalk/el-overlay.css';
import { debounce } from 'microconnect-common/utils/date';
import { InjectionKey } from 'vue';
import { MciButton } from '../Button';
import { MciMessageBox } from '../MessageBox';
import './index.scss';
import { useDrawerStore } from './store';

interface IDrawerProvide {
  setSteps(list: string[]): void;
  setStepIndex(index: number): void;
  setTitle(title: string): void;
}

export const drawerProvideKey =
  'drawerProvideKey' as unknown as InjectionKey<IDrawerProvide>;

export const useDrawer = () => {
  const ctx = inject(drawerProvideKey, null);

  return ctx;
};

export const MciDrawer = defineComponent({
  name: 'MciDrawer',
  props: {
    title: {
      type: [String, Object],
      default: ''
    },
    class: {
      type: String,
      default: ''
    },
    customClass: {
      type: String,
      default: ''
    },
    // 修改关闭二次确认校验
    modifyConfirm: {
      type: Boolean,
      default: false
    },
    beforeClose: {
      type: Function,
      default: null
    }
  },
  emits: ['opened', 'close'],
  setup(props, { emit, attrs }) {
    const drawerStore = useDrawerStore();
    const randomClassName = 'drawer-random' + String(Math.random()).slice(-5);
    let drawerBody: HTMLDivElement | null = null;
    const route = useRoute();
    const steps = ref<string[]>([]);
    const stepIndex = ref(-1);
    const activeTitle = ref();

    provide(drawerProvideKey, {
      setSteps(list) {
        steps.value = list;
      },
      setStepIndex(index) {
        stepIndex.value = index;
      },
      setTitle(title) {
        activeTitle.value = title;
      }
    });

    const beforeCloseHandle = async (done: TAnyFunction) => {
      if (props.modifyConfirm && drawerStore.modify) {
        await MciMessageBox.confirm('当前页面未保存，是否继续退出？', '提示');
        drawerStore.changeModify(false);
      }

      if (props.beforeClose) {
        props.beforeClose(done);
      } else {
        done?.();
      }
    };

    const openModifyConfirm = debounce(() => {
      drawerStore.changeModify(true);
    });

    const openedHandle = () => {
      drawerBody = document.querySelector(
        `.${randomClassName} .el-drawer__body`
      );
      if (drawerBody) {
        drawerBody.addEventListener('input', openModifyConfirm);
        drawerBody.addEventListener('change', openModifyConfirm);
      } else {
        console.error('ModifyConfirm 注册事件失败');
      }
      emit('opened');
    };

    const onClose = () => {
      emit('close');
      // 关闭抽屉时关闭校验提示
      ElNotification.closeAll();
    };

    watch(
      () => attrs.modelValue,
      (val) => {
        if (!val) drawerStore.changeModify(false);
      }
    );

    watch(
      () => route.name,
      () => {
        steps.value = [];
        stepIndex.value = -1;
        drawerStore.changeModify(false);
      }
    );

    watchEffect(() => {
      activeTitle.value = props.title;
    });

    onUnmounted(() => {
      if (drawerBody) {
        drawerBody.removeEventListener('input', openModifyConfirm);
        drawerBody.removeEventListener('change', openModifyConfirm);
      }
    });

    return {
      steps,
      stepIndex,
      beforeCloseHandle,
      openedHandle,
      onClose,
      drawerStore,
      randomClassName,
      openModifyConfirm,
      activeTitle
    };
  },
  render() {
    const titleSlot = () => {
      const renderExportBtn = () => {
        const filePath = this.drawerStore.filePath;
        if (filePath) {
          return (
            <MciButton v-download={filePath} size="small" class="mr-24">
              <i class="mci-icon-export"></i> {this.$t?.('导出')}
            </MciButton>
          );
        }
        return '';
      };

      const renderSteps = () => {
        const steps = this.steps;
        if (steps.length === 0) return null;

        const stepList = steps.map((text, index) => {
          const stepIndex = index + 1;
          const isDone = stepIndex < this.stepIndex;
          return (
            <div
              class={[
                'text-label-16 step-item',
                stepIndex === this.stepIndex ? 'is-active' : '',
                isDone ? 'is-done' : ''
              ]}
            >
              <span class="step-num mr-16 flex justify-center">
                {isDone ? (
                  <svg
                    class="mt-3 ml-1"
                    width="16"
                    height="16"
                    viewBox="0 0 16 16"
                    fill="none"
                    xmlns="http://www.w3.org/2000/svg"
                  >
                    <path
                      d="M6.43367 9.91797L12.6563 3.69531L13.5756 4.61455L6.43367 11.7564L1.9743 7.29709L2.89354 6.37785L6.43367 9.91797Z"
                      fill="#00AC97"
                    />
                  </svg>
                ) : (
                  stepIndex
                )}
              </span>
              {text}
            </div>
          );
        });

        return <div class="step-list ml-40 flex">{stepList}</div>;
      };

      return (
        <div class="flex justify-between">
          <div class="text-h3 mt-1 flex items-center">
            {this.activeTitle}
            {this.drawerStore.subTitle ? (
              <span
                title={this.drawerStore.subTitle}
                class="text-value-16_bold ml-8 max-w-780 truncate ..."
              >
                {this.drawerStore.subTitle}
              </span>
            ) : null}
            {renderSteps()}
          </div>
          {renderExportBtn()}
        </div>
      );
    };

    const slots: any = {
      title: titleSlot,
      default: this.$slots.default,
      footer: this.$slots.footer
    };

    return (
      <ElDrawer
        close-on-press-escape={false}
        destroy-on-close={true}
        custom-class={[
          'mci-drawer',
          this.class,
          this.customClass,
          this.randomClassName
        ]
          .filter(Boolean)
          .join(' ')}
        beforeClose={this.beforeCloseHandle}
        vSlots={slots}
        onOpened={this.openedHandle}
        onClose={this.onClose}
      />
    );
  }
});
